
<!DOCTYPE HTML>
<html lang="" >
    <head>
        <meta charset="UTF-8">
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>Composition · React in patterns</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="description" content="">
        <meta name="generator" content="GitBook 3.2.3">
        <meta name="author" content="Krasimir Tsonev">
        
        
    
    <link rel="stylesheet" href="../gitbook/style.css">

    
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-highlight/website.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-search/search.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css">
                
            
        

    

    
        
        <link rel="stylesheet" href="../styles/website.css">
        
    
        
    
        
    

        
    
    
    <meta name="HandheldFriendly" content="true"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="../gitbook/images/apple-touch-icon-precomposed-152.png">
    <link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">

    
    <link rel="next" href="./" />
    
    
    <link rel="prev" href="../chapter-03/" />
    

    </head>
    <body>
        
<div class="book">
    <div class="book-summary">
        
            
<div id="book-search-input" role="search">
    <input type="text" placeholder="Type to search" />
</div>

            
                <nav role="navigation">
                


<ul class="summary">
    
    

    

    
        
        
    
        <li class="chapter " data-level="1.1" data-path="../">
            
                <a href="../">
            
                    
                    Introduction
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2" data-path="../chapter-01/">
            
                <a href="../chapter-01/">
            
                    
                    In brief
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Foundation</li>
        
        
    
        <li class="chapter " data-level="2.1" data-path="../chapter-02/">
            
                <a href="../chapter-02/">
            
                    
                    Communication
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="2.1.1" data-path="../chapter-02/">
            
                <a href="../chapter-02/#input">
            
                    
                    Input
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.1.2" data-path="../chapter-02/">
            
                <a href="../chapter-02/#output">
            
                    
                    Output
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="2.2" data-path="../chapter-03/">
            
                <a href="../chapter-03/">
            
                    
                    Event handlers
            
                </a>
            

            
        </li>
    
        <li class="chapter active" data-level="2.3" data-path="./">
            
                <a href="./">
            
                    
                    Composition
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="2.3.1" data-path="./">
            
                <a href="./#using-reacts-children-api">
            
                    
                    Using React's children API
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.3.2" data-path="./">
            
                <a href="./#passing-a-child-as-a-prop">
            
                    
                    Passing a child as a prop
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.3.3" data-path="./">
            
                <a href="./#higher-order-component">
            
                    
                    Higher-order component
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.3.4" data-path="./">
            
                <a href="./#function-as-a-children-render-prop">
            
                    
                    Function as a children, render prop
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="2.4" data-path="../chapter-05/">
            
                <a href="../chapter-05/">
            
                    
                    Controlled and uncontrolled inputs
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.5" data-path="../chapter-06/">
            
                <a href="../chapter-06/">
            
                    
                    Presentational and container components
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Data flow</li>
        
        
    
        <li class="chapter " data-level="3.1" data-path="../chapter-07/">
            
                <a href="../chapter-07/">
            
                    
                    One direction data flow
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.2" data-path="../chapter-08/">
            
                <a href="../chapter-08/">
            
                    
                    Flux
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="3.2.1" data-path="../chapter-08/">
            
                <a href="../chapter-08/#flux-architecture-and-its-main-characteristics">
            
                    
                    Flux architecture and its main characteristics
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.2.2" data-path="../chapter-08/">
            
                <a href="../chapter-08/#implementing-a-flux-architecture">
            
                    
                    Implementing a Flux architecture
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="3.3" data-path="../chapter-09/">
            
                <a href="../chapter-09/">
            
                    
                    Redux
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="3.3.1" data-path="../chapter-09/">
            
                <a href="../chapter-09/#redux-architecture-and-its-main-characteristics">
            
                    
                    Redux architecture and its main characteristics
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.3.2" data-path="../chapter-09/">
            
                <a href="../chapter-09/#simple-counter-app-using-redux">
            
                    
                    Simple counter app using Redux
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

    
        
        <li class="header">Good to know</li>
        
        
    
        <li class="chapter " data-level="4.1" data-path="../chapter-10/">
            
                <a href="../chapter-10/">
            
                    
                    Dependency injection
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="4.1.1" data-path="../chapter-10/">
            
                <a href="../chapter-10/#using-reacts-context-prior-v-163">
            
                    
                    Using React's context (prior to v. 16.3)
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.1.2" data-path="../chapter-10/">
            
                <a href="../chapter-10/#using-reacts-context-v-163-and-above">
            
                    
                    Using React's context (v. 16.3 and above)
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.1.3" data-path="../chapter-10/">
            
                <a href="../chapter-10/#using-the-module-system">
            
                    
                    Using the module system
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="4.2" data-path="../chapter-11/">
            
                <a href="../chapter-11/">
            
                    
                    Styling
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="4.2.1" data-path="../chapter-11/">
            
                <a href="../chapter-11/#the-good-old-css-class">
            
                    
                    The good old CSS class
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.2.2" data-path="../chapter-11/">
            
                <a href="../chapter-11/#inline-styling">
            
                    
                    Inline styling
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.2.3" data-path="../chapter-11/">
            
                <a href="../chapter-11/#css-modules">
            
                    
                    CSS modules
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.2.4" data-path="../chapter-11/">
            
                <a href="../chapter-11/#styled-components">
            
                    
                    Styled-components
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="4.3" data-path="../chapter-12/">
            
                <a href="../chapter-12/">
            
                    
                    Integration of third-party libraries
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.4" data-path="../chapter-13/">
            
                <a href="../chapter-13/">
            
                    
                    React and separation of concerns
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Summary</li>
        
        
    
        <li class="chapter " data-level="5.1" data-path="../chapter-14/">
            
                <a href="../chapter-14/">
            
                    
                    Summary
            
                </a>
            

            
        </li>
    

    

    <li class="divider"></li>

    <li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            Published with GitBook
        </a>
    </li>
</ul>


                </nav>
            
        
    </div>

    <div class="book-body">
        
            <div class="body-inner">
                
                    

<div class="book-header" role="navigation">
    

    <!-- Title -->
    <h1>
        <i class="fa fa-circle-o-notch fa-spin"></i>
        <a href=".." >Composition</a>
    </h1>
</div>




                    <div class="page-wrapper" tabindex="-1" role="main">
                        <div class="page-inner">
                            
<div id="book-search-results">
    <div class="search-noresults">
    
                                <section class="normal markdown-section">
                                
                                <h1 id="composition">Composition</h1>
<p>One of the biggest benefits of React is composability. I personally don&apos;t know a framework that offers such an easy way to create and combine components. In this section we will explore a few composition techniques which proved to work well.</p>
<p>Let&apos;s get a simple example. Let&apos;s say that we have an application with a header and we want to place a navigation inside. We have three React components - <code>App</code>, <code>Header</code> and <code>Navigation</code>. They have to be nested into each other so we end up with the following dependencies:</p>
<pre><code class="lang-js">&lt;App&gt; -&gt; &lt;Header&gt; -&gt; &lt;Navigation&gt;
</code></pre>
<p>The trivial approach for combining these components is to reference them in the places where we need them.</p>
<pre><code class="lang-js"><span class="hljs-comment">// app.jsx</span>
<span class="hljs-keyword">import</span> Header <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./Header.jsx&apos;</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> &lt;Header /&gt;;
}

// Header.jsx
import Navigation from &apos;./Navigation.jsx&apos;;

export default function Header() {
  return &lt;header&gt;&lt;Navigation /&gt;&lt;/header&gt;;
}

// Navigation.jsx
export default function Navigation() {
  return (&lt;nav&gt; ... &lt;/nav&gt;);
}
</code></pre>
<p>However, by following this approach we introduced a couple of problems:</p>
<ul>
<li>We may consider the <code>App</code> as a place where we do our main composition. The <code>Header</code> though may have other elements like a logo, search field or a slogan. It will be nice if they are passed somehow from the <code>App</code> component so we don&apos;t create hard-coded dependencies. What if we need the same <code>Header</code> component but without the <code>Navigation</code>. We can&apos;t easily achieve that because we have the two bound tightly together.</li>
<li>It&apos;s difficult to test. We may have some business logic in the <code>Header</code> and in order to test it we have to create an instance of the component. However, because it imports other components we will probably create instances of those components too and it becomes heavy to test. We may break our <code>Header</code> test by doing something wrong in the <code>Navigation</code> component which is totally misleading. <em>(Note: to some extent <a href="https://facebook.github.io/react/docs/test-utils.html#shallow-rendering" target="_blank">shallow rendering</a> solves this problem by rendering only the <code>Header</code> without its nested children.)</em></li>
</ul>
<h2 id="using-reacts-children-api">Using React&apos;s children API</h2>
<p>In React we have the handy <a href="https://facebook.github.io/react/docs/multiple-components.html#children" target="_blank"><code>children</code></a> prop. That&apos;s how the parent reads/accesses its children. This API will make our Header agnostic and dependency-free:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Navigation</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span>
  );
}
export default function Header({ children }) {
  return <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>{ children }<span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>;
};
</span></code></pre>
<p>Notice also that if we don&apos;t use <code>{ children }</code> in <code>Header</code>, the <code>Navigation</code> component will never be rendered.</p>
<p>It now becomes easier to test because we may render the <code>Header</code> with an empty <code>&lt;div&gt;</code>. This will isolate the component and will let us focus on one piece of our application.</p>
<h2 id="passing-a-child-as-a-prop">Passing a child as a prop</h2>
<p>Every React component receives props. As we mentioned already there is no any strict rule about what these props are. We may even pass other components.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Title = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello there!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
}
<span class="hljs-keyword">const</span> Header = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">{ title, children }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
      { title }
      { children }
    <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span></span>
  );
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    &lt;Header title={ &lt;Title /&gt; }&gt;
      &lt;Navigation /&gt;
    &lt;/Header&gt;
  );
};
</code></pre>
<p>This technique is useful when a component like <code>Header</code> needs to take decisions about its children but don&apos;t bother about what they actually are. A simple example is a visibility component that hides its children based on a specific condition.</p>
<h2 id="higher-order-component">Higher-order component</h2>
<p>For a long period of time higher-order components were the most popular way to enhance and compose React elements. They look really similar to the <a href="http://robdodson.me/javascript-design-patterns-decorator/" target="_blank">decorator design pattern</a> because we have component wrapping and enhancing.</p>
<p>On the technical side the higher-order component is usually a function that accepts our original component and returns an enhanced/populated version of it. The most trivial example is as follows:</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> enhanceComponent = (Component) =&gt;
  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Enhance</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    render() {
      <span class="hljs-keyword">return</span> (
        &lt;Component {...this.props} /&gt;
      )
    }
  };

var OriginalTitle = () =&gt; &lt;h1&gt;Hello world&lt;/h1&gt;;
var EnhancedTitle = enhanceComponent(OriginalTitle);

class App extends React.Component {
  render() {
    return &lt;EnhancedTitle /&gt;;
  }
};
</code></pre>
<p>The very first thing that the higher-order component does is to render the original component. It&apos;s a good practice to proxy pass the <code>props</code> to it. This way we will keep the input of our original component. And here comes the first big benefit of this pattern - because we control the input of the component we may send something that the component usually has no access to. Let&apos;s say that we have a configuration setting that <code>OriginalTitle</code> needs:</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> config = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;path/to/configuration&apos;</span>);

<span class="hljs-keyword">var</span> enhanceComponent = (Component) =&gt;
  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Enhance</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    render() {
      <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Component</span>
          {<span class="hljs-attr">...this.props</span>}
          <span class="hljs-attr">title</span>=<span class="hljs-string">{</span> <span class="hljs-attr">config.appTitle</span> }
        /&gt;</span>
      )
    }
  };

var OriginalTitle  = ({ title }) =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{ title }<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>;
var EnhancedTitle = enhanceComponent(OriginalTitle);
</span></code></pre>
<p>The knowledge for the <code>appTitle</code> is hidden into the higher-order component. <code>OriginalTitle</code> knows only that it receives a <code>prop</code> called <code>title</code>. It has no idea that this is coming from a configuration file. That&apos;s a huge advantage because it allows us to isolate blocks. It also helps with the testing of the component because we can create mocks easily.</p>
<p>Another characteristic of this pattern is that we have a nice buffer for additional logic. For example, if our <code>OriginalTitle</code> needs data also from a remote server. We may query this data in the higher-order component and again send it as a prop.</p>
<p><span class="new-page"></span></p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> enhanceComponent = (Component) =&gt;
  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Enhance</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    <span class="hljs-keyword">constructor</span>(props) {
      <span class="hljs-keyword">super</span>(props);

      <span class="hljs-keyword">this</span>.state = { remoteTitle: <span class="hljs-literal">null</span> };
    }
    componentDidMount() {
      fetchRemoteData(<span class="hljs-string">&apos;path/to/endpoint&apos;</span>).then(data =&gt; {
        <span class="hljs-keyword">this</span>.setState({ remoteTitle: data.title });
      });
    }
    render() {
      <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Component</span>
          {<span class="hljs-attr">...this.props</span>}
          <span class="hljs-attr">title</span>=<span class="hljs-string">{</span> <span class="hljs-attr">config.appTitle</span> }
          <span class="hljs-attr">remoteTitle</span>=<span class="hljs-string">{</span> <span class="hljs-attr">this.state.remoteTitle</span> }
        /&gt;</span>
      )
    }
  };

var OriginalTitle  = ({ title, remoteTitle }) =&gt;
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{ title }{ remoteTitle }<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>;
var EnhancedTitle = enhanceComponent(OriginalTitle);
</span></code></pre>
<p>Again, the <code>OriginalTitle</code> knows that it receives two props and has to render them next to each other. Its only concern is how the data looks like not where it comes from and how.</p>
<p><em><a href="https://github.com/gaearon" target="_blank">Dan Abramov</a> made a really <a href="https://github.com/krasimir/react-in-patterns/issues/12" target="_blank">good point</a> that the actual creation of the higher-order component (i.e. calling a function like <code>enhanceComponent</code>) should happen at a component definition level. Or in other words, it&apos;s a bad practice to do it inside another React component because it may be slow and lead to performance issues.</em></p>
<p><br><br></p>
<h2 id="function-as-a-children-render-prop">Function as a children, render prop</h2>
<p>For the last couple of months, the React community started shifting in an interesting direction. So far in our examples the <code>children</code> prop was a React component. There is however a new pattern gaining popularity in which the same <code>children</code> prop is a JSX expression. Let&apos;s start by passing a simple object.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserName</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">b</span>&gt;</span>{ children.lastName }<span class="hljs-tag">&lt;/<span class="hljs-name">b</span>&gt;</span>,
      { children.firstName }
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> user = {
    firstName: <span class="hljs-string">&apos;Krasimir&apos;</span>,
    lastName: <span class="hljs-string">&apos;Tsonev&apos;</span>
  };
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">UserName</span>&gt;</span>{ user }<span class="hljs-tag">&lt;/<span class="hljs-name">UserName</span>&gt;</span></span>
  );
}
</code></pre>
<p>This may look weird but in fact is really powerful. Like for example when we have some knowledge in the parent component and don&apos;t necessary want to send it down to children. The example below prints a list of TODOs. The <code>App</code> component has all the data and knows how to determine whether a TODO is completed or not. The <code>TodoList</code> component simply encapsulate the needed HTML markup.</p>
<p><br><br><br><br></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TodoList</span>(<span class="hljs-params">{ todos, children }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&apos;main-section&apos;</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&apos;todo-list&apos;</span>&gt;</span>{
        todos.map((todo, i) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{</span> <span class="hljs-attr">i</span> }&gt;</span>{ children(todo) }<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))
      }<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span></span>
  );
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> todos = [
    { label: <span class="hljs-string">&apos;Write tests&apos;</span>, status: <span class="hljs-string">&apos;done&apos;</span> },
    { label: <span class="hljs-string">&apos;Sent report&apos;</span>, status: <span class="hljs-string">&apos;progress&apos;</span> },
    { label: <span class="hljs-string">&apos;Answer emails&apos;</span>, status: <span class="hljs-string">&apos;done&apos;</span> }
  ];
  <span class="hljs-keyword">const</span> isCompleted = todo =&gt; todo.status === <span class="hljs-string">&apos;done&apos;</span>;
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">TodoList</span> <span class="hljs-attr">todos</span>=<span class="hljs-string">{</span> <span class="hljs-attr">todos</span> }&gt;</span>
      {
        todo =&gt; isCompleted(todo) ?
          <span class="hljs-tag">&lt;<span class="hljs-name">b</span>&gt;</span>{ todo.label }<span class="hljs-tag">&lt;/<span class="hljs-name">b</span>&gt;</span> :
          todo.label
      }
    <span class="hljs-tag">&lt;/<span class="hljs-name">TodoList</span>&gt;</span></span>
  );
}
</code></pre>
<p>Notice how the <code>App</code> component doesn&apos;t expose the structure of the data. <code>TodoList</code> has no idea that there is <code>label</code> or <code>status</code> properties.</p>
<p>The so called <em>render prop</em> pattern is almost the same except that we use the <code>render</code> prop and not <code>children</code> for rendering the todo.</p>
<p><br><br><br></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TodoList</span>(<span class="hljs-params">{ todos, render }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&apos;main-section&apos;</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&apos;todo-list&apos;</span>&gt;</span>{
        todos.map((todo, i) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{</span> <span class="hljs-attr">i</span> }&gt;</span>{ render(todo) }<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))
      }<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">return</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">TodoList</span>
    <span class="hljs-attr">todos</span>=<span class="hljs-string">{</span> <span class="hljs-attr">todos</span> }
    <span class="hljs-attr">render</span>=<span class="hljs-string">{</span>
      <span class="hljs-attr">todo</span> =&gt;</span> isCompleted(todo) ?
        <span class="hljs-tag">&lt;<span class="hljs-name">b</span>&gt;</span>{ todo.label }<span class="hljs-tag">&lt;/<span class="hljs-name">b</span>&gt;</span> : todo.label
    } /&gt;
);
</span></code></pre>
<p>These two patterns, <em>function as children</em> and <em>render prop</em> are probably one of my favorite ones recently. They provide flexibility and help when we want to reuse code. They are also a powerful way to abstract imperative code.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DataProvider</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-keyword">super</span>(props);

    <span class="hljs-keyword">this</span>.state = { data: <span class="hljs-literal">null</span> };
    setTimeout(() =&gt; <span class="hljs-keyword">this</span>.setState({ data: <span class="hljs-string">&apos;Hey there!&apos;</span> }), <span class="hljs-number">5000</span>);
  }
  render() {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.data === <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>{ this.props.render(this.state.data) }<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span></span>
    );
  }
}
</code></pre>
<p><code>DataProvider</code> renders nothing when it first gets mounted. Five seconds later we update the state of the component and render a <code>&lt;section&gt;</code> followed by what is <code>render</code> prop returning. Imagine that this same component fetches data from a remote server and we want to display it only when it is available.</p>
<pre><code class="lang-js">&lt;DataProvider render={ data =&gt; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>The data is here!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span> } /&gt;
</code></pre>
<p>We do say what we want to happen but not how. That is hidden inside the <code>DataProvider</code>. These days we used this pattern at work where we had to restrict some UI to certain users having <code>read:products</code> permissions. And we used the <em>render prop</em> pattern.</p>
<pre><code class="lang-js">&lt;Authorize
  permissionsInclude={[ <span class="hljs-string">&apos;read:products&apos;</span> ]}
  render={ () =&gt; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ProductsList</span> /&gt;</span> } /&gt;
</span></code></pre>
<p>Pretty nice and self-explanatory in a declarative fashion. <code>Authorize</code> goes to our identity provider and checks what are the permissions of the current user. If he/she is allowed to read our products we render the <code>ProductList</code>.</p>
<h2 id="final-thoughts">Final thoughts</h2>
<p>Did you wonder why HTML is still here. It was created in the dawn of the internet and we still use it. That is because it&apos;s highly composable. React and its JSX looks like HTML on steroids and as such it comes with the same capabilities. So, make sure that you master the composition because that is one of the biggest benefits of React.</p>

                                
                                </section>
                            
    </div>
    <div class="search-results">
        <div class="has-results">
            
            <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
            <ul class="search-results-list"></ul>
            
        </div>
        <div class="no-results">
            
            <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
            
        </div>
    </div>
</div>

                        </div>
                    </div>
                
            </div>

            
                
                <a href="../chapter-03/" class="navigation navigation-prev " aria-label="Previous page: Event handlers">
                    <i class="fa fa-angle-left"></i>
                </a>
                
                
                <a href="./#using-reacts-children-api" class="navigation navigation-next " aria-label="Next page: Using React's children API">
                    <i class="fa fa-angle-right"></i>
                </a>
                
            
        
    </div>

    <script>
        var gitbook = gitbook || [];
        gitbook.push(function() {
            gitbook.page.hasChanged({"page":{"title":"Composition","level":"2.3","depth":1,"next":{"title":"Using React's children API","level":"2.3.1","depth":2,"anchor":"#using-reacts-children-api","path":"chapter-04/README.md","ref":"chapter-04/README.md#using-reacts-children-api","articles":[]},"previous":{"title":"Event handlers","level":"2.2","depth":1,"path":"chapter-03/README.md","ref":"chapter-03/README.md","articles":[]},"dir":"ltr"},"config":{"plugins":[],"root":"./book","styles":{"website":"./styles/website.css","ebook":"./styles/ebook.css","pdf":"./styles/ebook.css"},"pluginsConfig":{"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"theme":"default","author":"Krasimir Tsonev","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a5","chapterMark":"pagebreak","pageBreaksBefore":"//*[@class='new-page']","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"React in patterns","gitbook":"3.2.3","description":"A book about common design patterns used while developing with React."},"file":{"path":"chapter-04/README.md","mtime":"2023-07-06T05:38:39.115Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2025-01-27T05:24:55.061Z"},"basePath":"..","book":{"language":""}});
        });
    </script>
</div>

        
    <script src="../gitbook/gitbook.js"></script>
    <script src="../gitbook/theme.js"></script>
    
        
        <script src="../gitbook/gitbook-plugin-search/search-engine.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search/search.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-sharing/buttons.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
        
    

    </body>
</html>

